package com.tedu.ivos.autit.service.impl;

import com.tedu.ivos.application.mapper.AppMapper;
import com.tedu.ivos.application.pojo.entity.App;
import com.tedu.ivos.autit.pojo.dto.AuditQuery;
import com.tedu.ivos.autit.pojo.dto.AuditSaveFormParam;
import com.tedu.ivos.autit.pojo.entity.Audit;
import com.tedu.ivos.autit.pojo.vo.AuditVO;
import com.tedu.ivos.autit.service.IAuditService;
import com.tedu.ivos.autit.mapper.AuditMapper;
import com.tedu.ivos.base.enums.AppStatusEnum;
import com.tedu.ivos.base.enums.AuditStatusEnum;
import com.tedu.ivos.base.exception.ServiceException;
import com.tedu.ivos.user.mapper.UserMapper;
import com.tedu.ivos.user.pojo.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Slf4j
@Transactional
@Service
public class AuditService implements IAuditService {

    @Autowired
    AuditMapper auditMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    AppMapper appMapper;

    @Override
    public void insertAudit(App app) {
        log.debug("为当前申请单生成对应的审批单业务:参数={}",app);
        List<Long> userIdList = app.getAuditUserIdList();
        for(int i=0; i<userIdList.size(); i++){
            Audit audit = new Audit();
            audit.setApplicationId(app.getId());
            audit.setAuditUserId(userIdList.get(i));
            audit.setAuditSort(i);
            if(i==0){
                audit.setAuditStatus(AuditStatusEnum.MY_PENDING.getCode());
            }else{
                audit.setAuditStatus(AuditStatusEnum.PENDING.getCode());
            }
            audit.setCreateTime(new Date());
            auditMapper.insertAudit(audit);
        }
    }

    @Override
    public List<AuditVO> selectAuditByAppId(Long id) {
        log.debug("查询审批人业务：参数={}",id);
        return auditMapper.selectAuditByAppId(id);
    }

    @Override
    public List<AuditVO> select(AuditQuery auditQuery) {
        log.debug("查询审批单业务：参数={}",auditQuery);
        List<AuditVO> auditVOList = auditMapper.select(auditQuery);
        log.debug("查询审批单业务id：参数={}",auditVOList.toString());
        for(int i=0; i<auditVOList.size(); i++){
            AuditVO auditVO = auditVOList.get(i);
            assignAuditUserList(auditVO);
            log.debug("查询审批单业务id：参数={}",auditVO);
        }
        return auditVOList;
    }

    private void assignAuditUserList(AuditVO auditVO) {
        log.debug("完善审批单数据业务：参数={}",auditVO);
        List<Long> auditUserIdList = new ArrayList<>();
        List<String> auditUsernameList = new ArrayList<>();
        List<AuditVO> auditVOList = auditMapper.selectAuditByAppId(auditVO.getApplicationId());
        for(int i=0;i<auditVOList.size();i++){
            Long userId = auditVOList.get(i).getAuditUserId();
            auditUserIdList.add(userId);
            UserVO userVO = userMapper.selectById(userId);
            auditUsernameList.add(userVO.getUsername());
            log.debug("完善审批单数据业务：result={}",auditUsernameList.get(i));
        }
        StringJoiner stringJoiner = new StringJoiner(",");
        for(String username : auditUsernameList){
            stringJoiner.add(username);
        }
        auditVO.setAuditUsernameList(stringJoiner.toString());
        auditVO.setAuditUserIdList(auditUserIdList);
    }

    @Override
    public void update(AuditSaveFormParam auditSaveFormParam) {
        log.debug("更新审批单业务：参数={}",auditSaveFormParam);
        Audit audit = new Audit();
        BeanUtils.copyProperties(auditSaveFormParam,audit);
        audit.setUpdateTime(new Date());
        App app = new App();
        app.setId(audit.getApplicationId());
        app.setUpdateTime(new Date());
        //需要判断当前要做通过处理还是驳回处理
        if(audit.getAuditStatus().equals(AuditStatusEnum.AUDITED.getCode())){
            log.debug("审核通过：参数={}",audit);
            auditMapper.update(audit);//更新当前的审批单
            /*继续查是否有其它的审批单：其它审批单与当前审批单对应的申请单时同一个*/
            AuditQuery auditQuery = new AuditQuery();
            auditQuery.setApplicationId(audit.getApplicationId());
            //根据申请单id查询当前申请单对应的所有未审批的审批单总数，注意：当前审批单已审批通过
            Integer count = auditMapper.selectRestAuditCount(auditQuery);
            log.debug("count:"+count);
            if (count>0){//还有未审核的数据
                //下一条审批次序是当前审批数据的次序+1
                auditQuery.setAuditSort(audit.getAuditSort()+1);
                //根据申请单id与审批次序查出当前审批单之后的下一条审批数据
                List<AuditVO> auditVOList = auditMapper.select(auditQuery);
                if(auditVOList!=null && auditVOList.size()>0){
                    AuditVO auditVO = auditVOList.get(0);
                    //创建空对象代表第二个审批对象
                    Audit audit1 = new Audit();
                    audit1.setId(auditVO.getId());
                    audit1.setAuditStatus(AuditStatusEnum.MY_PENDING.getCode());
                    auditMapper.update(audit1);
                }
                app.setStatus(AppStatusEnum.AUDIT.getCode());//更新申请单状态为 审核中
                appMapper.update(app);
            }else {//没有未审核的数据
                app.setStatus(AppStatusEnum.AUDITED.getCode());//更新申请单状态为 已审核
                appMapper.update(app);
            }
        }else{
            log.debug("审核驳回：参数={}",audit);
            auditMapper.update(audit);
            AuditQuery auditQuery = new AuditQuery();
            auditQuery.setApplicationId(audit.getApplicationId());
            //根据申请单id与审批次序查出当前审批单之后的下一条审批数据
            List<AuditVO> auditVOList = auditMapper.select(auditQuery);
            if(auditVOList!=null && auditVOList.size()>0){
                log.debug("审核驳回,删除剩余未审核：参数={}",audit);
                for(int i=0;i<auditVOList.size();i++){
                    AuditVO auditVO = auditVOList.get(i);
                    if(AuditStatusEnum.PENDING.getCode().equals(auditVO.getAuditStatus())){
                        auditMapper.deleteById(auditVO.getId());
                    }
                }
            }
            log.debug("更新申请单设置驳回原因：参数={}",app);
            app.setStatus(AppStatusEnum.REJECT.getCode());//更新申请单状态为 驳回
            app.setRejectReason(auditSaveFormParam.getRejectReason());//添加驳回原因
            appMapper.update(app);
        }
    }

}
